Question 1

Question 2

Question 1

Do you design software when you “write” a program? What makes software design different from coding?
        
When you "write" a program, you're typically involved in both software design and coding,
but they represent different stages and activities within the software development process.
Software design involves creating a plan or blueprint for how the software will be
structured and behave. This includes defining the architecture, data structures, algorithms,
and interfaces of the software system. During the design phase, decisions are made about
how different components will interact with each other to achieve the desired functionality.
On the other hand, coding, or programming, is the process of translating the design into
actual code using a programming language. This involves writing instructions in a specific
syntax that the computer can understand and execute.
        


Question 2

How do we assess the quality of a software design?
        
1. Modularity: A well-designed software system should be modular, with distinct
and loosely coupled components. Modularity allows for easier maintenance,
testing, and reuse of components.
2. Flexibility: The design should be flexible enough to accommodate changes and
updates without requiring extensive modifications to the entire system. This
includes support for future enhancements and the ability to adapt to evolving
requirements.
3. Scalability: A good design should be scalable, meaning it can handle increased
workload or accommodate growth in data volume without significant
performance degradation or redesign effort.
4. Maintainability: The design should be easy to understand, modify, and debug.
Clear and well-documented code, along with adherence to coding standards and
best practices, contribute to maintainability.
5. Performance: The design should be optimized for performance, ensuring that the
software meets its performance requirements while utilizing system resources
efficiently.
6. Security: The design should incorporate appropriate security measures to protect
sensitive data and prevent unauthorized access or malicious attacks.
7. Usability: The design should prioritize user experience and usability, making it
intuitive and easy to use for end-users.
8. Adherence to Requirements: The design should closely align with the specified
requirements, ensuring that the software meets the needs of its users and
stakeholders.
9. Extensibility: The design should allow for easy extension and customization,
enabling the addition of new features or functionality without major redesign
efforts.
10. Consistency: The design should maintain consistency in its structure, naming
conventions, and coding style throughout the system, making it easier for
developers to understand and work with.



Question 3

What benefits can be obtained from designing based on the following concepts:
        
Designing based on the following concepts can offer several benefits:
1. Abstraction: Abstraction allows designers to focus on essential aspects of the
system while hiding unnecessary details. It simplifies the design process, enhances
understandability, and promotes reusability by creating generalized and reusable
components.
2. Software Architecture: A well-defined software architecture provides a blueprint
for the system's structure, organization, and behavior. It enables scalability,
maintainability, and adaptability by defining clear interfaces between components,
facilitating parallel development, and supporting system evolution.
3. Separation of Concerns: Separating different aspects of the system, such as
presentation, business logic, and data management, into distinct modules or layers
enhances modularity and facilitates easier maintenance, testing, and evolution of
the system. It also promotes code readability and reusability.
4. Modularity: Modularity involves breaking down the system into smaller, cohesive
modules or components with well-defined interfaces. This promotes code reuse,
simplifies testing and debugging, and allows for easier maintenance and evolution
of the system by isolating changes to specific modules.
5. Information Hiding: Information hiding restricts access to internal details of a
module, exposing only necessary interfaces to the outside world. This
encapsulation enhances security, reduces complexity, and facilitates independent
development and evolution of modules without affecting other parts of the system.
6. Functional Independence: Designing components with functional independence
ensures that each module performs a specific and well-defined function without
unnecessary dependencies on other modules. This promotes flexibility, facilitates
parallel development, and reduces the ripple effects of changes in one module on
others.

7. Refinement: Refinement involves progressively elaborating the design from high-
level abstractions to lower-level details. It allows designers to iteratively refine and

improve the design based on evolving requirements, feedback, and insights gained
during the development process, resulting in a more robust and optimized solution.
        


Question 4

Discuss the relationship between the concept of information hiding as an attribute of effective modularity and the concept of module independence.
        
Information hiding and module independence are complementary concepts that work
together to promote effective modularity in software design. Information hiding ensures
that modules are encapsulated and only expose essential interfaces, while module
independence enables modules to operate autonomously and be developed and
maintained independently, leading to more robust, flexible, and maintainable software
systems.   



Question 5

Does “refactoring” mean that you modify the entire design iteratively? If not, what does it mean?
        
No, "refactoring" does not necessarily mean modifying the entire design iteratively.
Refactoring refers to the process of making changes to the internal structure or design of
code without altering its external behavior. It is a disciplined technique for restructuring
existing code to improve readability, maintainability, and extensibility without changing
its observable functionality.